package com.nwpu.bigdata.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nwpu.bigdata.model.Event;
import com.nwpu.bigdata.model.Rule;
import com.nwpu.bigdata.service.EventService;
import com.nwpu.bigdata.service.RuleService;
import com.nwpu.bigdata.util.FuncUtil;

/**
 * @version:2018年7月20日下午3:21:54
 */

/**
 * @author Administrator
 *
 */
@Service
public class RuleDetectionServiceImpl implements com.nwpu.bigdata.service.RuleDetectionService {

    /*
     * 解析从数据库拿出来的相关规则信息
     */

    @Autowired
    RuleService ruleService;
    @Autowired
    FuncUtil function;
    @Autowired
    EventService eventService;

    @Override
    public void ruleProcess() {
        Long id;
        String hostName;
        String hostType;
        String metricName;
        String functionName;
        int parameter;
        String paraUnit;
        String operator;
        BigDecimal triggerThreshold;
        BigDecimal recoverThreshold;


        try {
            //List<String> list = new LinkedList<String>();
            List<Rule> ruleList = ruleService.findRuleDetail();
            
            for (Rule rule : ruleList) {
                id = rule.getId();//得到规则的id
                hostName = rule.getHost().getHostName();//得到待检测规则的主机名
                hostType = rule.getHostType().getTypeName();
                metricName = rule.getMetric().getMetricName();//得到待检测规则的指标名
                functionName = rule.getCheckFunc().getFuncName();//得到待检测规则的函数名
                parameter = rule.getFuncParameter();//得到相应的参数
                paraUnit = rule.getParaUnit();
                operator = rule.getOperator();
                triggerThreshold = rule.getTriggerThreshold();//得到该规则的阈值
                recoverThreshold = rule.getRecoverThreshold();//得到规则的恢复阈值
                //得到改规则值,参数包括主机名，主机type，指标名，函数名，参数，以及参数单位
                System.out.println(hostName+","+hostType+","+metricName+","+functionName+","+parameter+","+paraUnit);
                
                double value = getFunctionValue(hostName, hostType, metricName, functionName, parameter, paraUnit);
                //将值插入到事件表中

                //对得到结果进行判断，判断该结果是否大于阈值
                insertEnvent(id, value, operator, triggerThreshold, recoverThreshold);
            }

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    /*
     * 通过Function中的相应函数计算相关指标当前的值
     */
    @Override
    public double getFunctionValue(String hostName, String hostType, String metricName, String functionName, int parameter, String paraUnit) {

        double value = 0;
        System.out.println(hostName+","+hostType+","+metricName+","+functionName+","+parameter+","+paraUnit);

        if(hostType.equals("node") || hostType.equals("cluster") || hostType.equals("pod") || hostType.equals("ns") || hostType.equals("pod_container")){
        	System.out.println(hostType);
        	System.out.println(function.avg(hostType, hostName, metricName, parameter, paraUnit));
            switch (functionName) {
                case "avg":
                    value = (double) function.avg(hostType, hostName, metricName, parameter, paraUnit);
                    break;
                case "count":
                    value = (double) function.count(hostType, hostName, metricName, parameter, paraUnit);
                    break;
                case "max":
                    value = (double) function.max(hostType, hostName, metricName, parameter, paraUnit);
                    break;
                case "min":
                    value = (double) function.min(hostType, hostName, metricName, parameter, paraUnit);
                    break;
                case "last":
                    value = (double) function.last(hostType, hostName, metricName, parameter, paraUnit);
                    break;
            }

        } else {
            switch (functionName) {
                case "avg":
                    value = (double) function.avg(parameter, paraUnit, hostName, hostType, metricName);
                    break;
                case "count":
                    value = (double) function.count(parameter, paraUnit, hostName, hostType, metricName);
                    break;
                case "max":
                    value = (double) function.max(parameter, paraUnit, hostName, hostType, metricName);
                    break;
                case "min":
                    value = (double) function.min(parameter, paraUnit, hostName, hostType, metricName);
                    break;
                case "last":
                    value = (double) function.last(parameter, paraUnit, hostName, hostType, metricName);
                    break;
                case "sum":
                    value = (double) function.last(parameter, paraUnit, hostName, hostType, metricName);
                    break;
            }
        }

System.out.println(value);
        return value;
    }

    /*
     * 对检测结果进行判断，并将违反规则的相关信息添加到事件表中
     */

    //triggerThreshold.compareTo(dValue)将阈值和value进行比较，如果value值大于阈值则返回1，如果等于返回0，如果小于返回-1
    @Override
    public void insertEnvent(Long ruleId, double value, String operator, BigDecimal triggerThreshold, BigDecimal recoverThreshold) {

        BigDecimal dValue = new BigDecimal(value);
        Byte isEnabled = 1;
        Event event = new Event(ruleId, new Date(), dValue, isEnabled, new Date(), new Date());
        switch (operator) {
            case ">":
                if (dValue.compareTo(triggerThreshold) > 0) {
                    //如果大于等于阈值则产生一条事件插入事件表中
                    eventService.insertEve(event);
                    break;

                }/*else if(dValue.compareTo(recoverThreshold) <= 0){
				return;
                	//如果小于阈值，则判断该值是否小于恢复阈值，如果小于恢复阈值，则update事件表中某一事件的isenable值
			}*/
                break;
            case "=":
                if (dValue.compareTo(triggerThreshold) == 0) {
                    //如果大于等于阈值则产生一条事件插入事件表中
                    eventService.insertEve(event);
                    break;
                }/*else if(dValue.compareTo(recoverThreshold) <= 0){
				
                	return;
                	//如果小于阈值，则判断该值是否小于恢复阈值，如果小于恢复阈值，则update事件表中某一事件的isenable值
			}*/
                break;
            case "<":
                if (dValue.compareTo(triggerThreshold) < 0) {
                    //如果大于等于阈值则产生一条事件插入事件表中
                    eventService.insertEve(event);
                    break;
                }/*else if(dValue.compareTo(recoverThreshold) >= 0){
				
                	return;
                	//如果小于阈值，则判断该值是否小于恢复阈值，如果小于恢复阈值，则update事件表中某一事件的isenable值
				
			}*/
                break;
            default:
                break;
        }


    }


}
